﻿using System.Threading;

namespace Core.RVO
{
    /**
     * <summary>Defines a worker.</summary>
     */
    public class Worker : Core.Component, IAwake<ManualResetEvent>
    {
        private ManualResetEvent mDoneEvent;
        private int mEnd;
        private int mStart;

        private RVOSystem sys;

        public void Awake(ManualResetEvent done_event)
        {
            mDoneEvent = done_event;
            sys = Entity as RVOSystem;
        }

        public override void Dispose()
        {
            if (IsDisposed) return;
            base.Dispose();
        }

        public void SetIndex(int start, int end)
        {
            mStart = start;
            mEnd = end;
        }

        /**
         * <summary>Performs a simulation step.</summary>
         *
         * <param name="obj">Unused.</param>
         */
        public void Step(object obj)
        {
            for (int index = mStart; index < mEnd; ++index)
            {
                var agent = sys.Agents.GetByIndex(index);
                agent.ComputeNeighbors();
                agent.ComputeNewVelocity();
            }
            mDoneEvent.Set();
        }

        /**
         * <summary>updates the two-dimensional position and
         * two-dimensional velocity of each agent.</summary>
         *
         * <param name="obj">Unused.</param>
         */
        public void Update(object obj)
        {
            for (int index = mStart; index < mEnd; ++index)
            {
                var agent = sys.Agents.GetByIndex(index);
                agent.Update();
            }

            mDoneEvent.Set();
        }
    }

}
